package com.construction.api.service.impl;

import cn.hutool.core.bean.BeanUtil;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.construction.api.domain.model.result.PageResult;
import com.construction.api.service.IService;
import org.springframework.beans.factory.annotation.Autowired;

import java.io.Serializable;
import java.lang.reflect.ParameterizedType;
import java.util.List;
import java.util.stream.Collectors;

/**
 * @author dybin
 * @Date: 2021-07-04 13:39
 */
public abstract class AbstractUsualService<T, K extends Serializable, E> implements IService<T, K, E> {

    @Autowired
    protected BaseMapper<T> baseMapper;

    protected Class<T> tClazz;
    protected Class<E> eClazz;

    public AbstractUsualService() {
        ParameterizedType pt = (ParameterizedType) this.getClass().getGenericSuperclass();
        this.tClazz = (Class<T>) pt.getActualTypeArguments()[0];
        this.eClazz = (Class<E>) pt.getActualTypeArguments()[2];
    }

    @Override
    public E insert(T t) {
        baseMapper.insert(t);
        return tWrapperE(t);
    }

    @Override
    public E update(K k, T t) {
        baseMapper.updateById(t);
        return tWrapperE(t);
    }

    @Override
    public void delete(K id) {
        baseMapper.deleteById(id);
    }

    @Override
    public E get(K id) {
        return tWrapperE(baseMapper.selectById(id));
    }

    @Override
    public PageResult queryPageList(int size,
                                    int current,
                                    T t) {
        Page<T> page = new Page<>(current, size);
        page = baseMapper.selectPage(page, new QueryWrapper<T>().setEntity(t));
        page.setRecords((List<T>) listTWrapperE(page.getRecords()));
        return BeanUtil.copyProperties(page, PageResult.class);
    }

    @Override
    public List<E> queryList(T t) {
        List<T> list = baseMapper.selectList(new QueryWrapper<T>().setEntity(t));
        return listTWrapperE(list);
    }

    public E tWrapperE(T t) {
        return (this.tClazz == this.eClazz) ? (E) t : BeanUtil.copyProperties(t, eClazz);
    }

    public List<E> listTWrapperE(List<T> t) {
        return (this.tClazz == this.eClazz)
                ? (List<E>) t
                : t.stream().map(sourceObj -> BeanUtil.copyProperties(sourceObj, eClazz)).collect(Collectors.toList());
    }

}
